// AnalysisServiceImpl.java
package com.sulent.frame.web.service.impl;


import com.sulent.frame.web.service.AnalysisModel;
import com.sulent.frame.web.service.AnalysisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

@Service
public class AnalysisServiceImpl implements AnalysisService {

    @Autowired
    private List<AnalysisModel> analysisModels; // 注入所有实现AnalysisModel的Bean

    private final ExecutorService executor = Executors.newFixedThreadPool(6); // 根据需要调整线程池大小

    @Override
    public Map<String, Object> performAnalysis(Map<String, Object> input) throws InterruptedException, ExecutionException, TimeoutException {
        List<CompletableFuture<Map<String, Object>>> futures = new ArrayList<>();

        for (AnalysisModel model : analysisModels) {
            CompletableFuture<Map<String, Object>> future = CompletableFuture.supplyAsync(() -> {
                return retryCall(() -> model.analyze(input));
            }, executor);
            futures.add(future);
        }

        CompletableFuture<Void> allFutures = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));

        // 等待所有任务完成或超时
        allFutures.get(10, TimeUnit.SECONDS); // 总超时时间，例如10秒

        Map<String, Object> results = new HashMap<>();
        for (CompletableFuture<Map<String, Object>> future : futures) {
            results = mergeResults(results, future.join());
        }

        return results;
    }

    private Map<String, Object> mergeResults(Map<String, Object> acc, Map<String, Object> newResults) {
        Map<String, Object> merged = new HashMap<>(acc);
        merged.putAll(newResults);
        return merged;
    }

    /**
     * # 重试次数
     * retry.maxAttempts=3
     * # 初始间隔时间（毫秒）
     * retry.backoff.initialInterval=1000
     * # 最大间隔时间（毫秒）
     * retry.backoff.maxInterval=5000
     * # 间隔时间乘数
     * retry.backoff.multiplier=2.0
     * @param task
     * @return
     */
    @Retryable(
        value = {TimeoutException.class, RuntimeException.class},
        maxAttemptsExpression = "${retry.maxAttempts:3}",
        backoff = @Backoff(delayExpression = "${retry.backoff.initialInterval:1000}",
                           multiplierExpression = "${retry.backoff.multiplier:2.0}",
                           maxDelayExpression = "${retry.backoff.maxInterval:5000}")
    )
    private Map<String, Object> retryCall(Callable<Map<String, Object>> task) {
        try {
            return task.call();
        } catch (Exception e) {
            throw new CompletionException(e);
        }
    }
}